package com.li.toolkit.utils;

import com.li.toolkit.constant.LogConst;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;

/**
 * @author LiDong
 * @version 1.0.0
 * @createTime 2/19/2022 10:12 AM
 */
public final class TimeUtils {

    private static final Logger logger = LoggerFactory.getLogger(TimeUtils.class);

    private TimeUtils() {
    }

    /**
     * 标准24小时日期格式
     */
    private static final String STANDARD_DATETIME_24 = "yyyy-MM-dd HH:mm:ss";

    /**
     * 标准12小时日期格式
     */
    private static final String STANDARD_DATETIME_12 = "yyyy-MM-dd hh:mm:ss";

    /**
     * 标准年月日
     */
    private static final String STANDARD_DATE = "yyyy-MM-dd";


    /**
     * Java 8 保证线程安全
     */
    public static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern(STANDARD_DATETIME_24);


    /**
     * Java 8 保证线程安全
     */
    public static LocalDate parse(String dateString) {
        return LocalDate.parse(dateString, DATE_TIME_FORMATTER);
    }


    /**
     * Java 8 保证线程安全
     */
    public static String format(LocalDate target) {
        return target.format(DATE_TIME_FORMATTER);
    }


    /**
     * 保证线程安全
     */
    private static final ThreadLocal<DateFormat> threadLocal = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));

    /**
     * 保证线程安全
     */
    public static Date parse(String formatPattern, String dateString) throws ParseException {
        return threadLocal.get().parse(dateString);
    }

    /**
     * 保证线程安全
     */
    public static String format(String formatPattern, Date date) {
        return threadLocal.get().format(date);
    }


    /**
     * 获得当前的时间戳
     *
     * @return long
     */
    public static long getCurrentTimestamp() {
        return System.currentTimeMillis();
    }

    /**
     * 获得当前标准时间 24小时制
     *
     * @return String
     */
    public static String getDateTime24() {
        Date date = new Date();
        SimpleDateFormat simpleFormatter = new SimpleDateFormat(STANDARD_DATETIME_24);
        return simpleFormatter.format(date);
    }

    /**
     * 获得当前标准时间 12小时制
     *
     * @return String
     */
    public static String getDateTime12() {
        Date date = new Date();
        SimpleDateFormat simpleFormatter = new SimpleDateFormat(STANDARD_DATETIME_12);
        return simpleFormatter.format(date);
    }


    /**
     * 格式化传入的字符串类型的时间：2020-10-12 20:51:34.0000
     *
     * @param str 时间字符串
     * @return String
     */
    public static String parseDateTime(String str) {
        SimpleDateFormat simpleDateFormat;
        if (str.contains(":")) {
            simpleDateFormat = new SimpleDateFormat(STANDARD_DATETIME_24);
        } else {
            simpleDateFormat = new SimpleDateFormat(STANDARD_DATE);
        }
        try {
            Date date = simpleDateFormat.parse(str);
            return simpleDateFormat.format(date);
        } catch (ParseException e) {
            logger.error("paraseDateTime() error occur :{}", e.getMessage());
            return null;
        }
    }

    /**
     * String 类型的时间转换为 Date 类型的时间
     *
     * @param dateTime 时间字符串
     * @return Date
     */
    public static Date parseStrTime(String dateTime) {
        SimpleDateFormat simpleDateFormat;
        if (dateTime.contains(":")) {
            simpleDateFormat = new SimpleDateFormat(STANDARD_DATETIME_24);
        } else {
            simpleDateFormat = new SimpleDateFormat(STANDARD_DATE);
        }
        try {
            return simpleDateFormat.parse(dateTime);
        } catch (ParseException e) {
            logger.error("covertStrTime() error occur :{}", e.getMessage());
            return null;
        }
    }

    /**
     * 将时间戳转换为标准时间：yyyy-MM-dd HH:mm:ss
     *
     * @param timestamp 时间戳
     * @return String
     */
    public static String timeStampToTime(String timestamp) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(STANDARD_DATETIME_24);
        long time = Long.parseLong(timestamp);
        Date date = new Date(time);
        return simpleDateFormat.format(date);
    }

    /**
     * 将时间字符串转换为
     *
     * @param str str
     * @return String
     */
    public static String timeToTimeStamp(String str) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(STANDARD_DATETIME_24);
        try {
            Date date = simpleDateFormat.parse(str);
            long time = date.getTime();
            return String.valueOf(time);
        } catch (ParseException e) {
            logger.error("timeToTimeStamp() error occur:{}", e.getMessage());
            return StrUtils.EMPTY_STR;
        }
    }


    /**
     * 计算出当前时间的前或者后几天的时间，
     * 例如：当前时间的后5天的时间为：2020-10-17 21:42:35
     * 当前时间的前5天的时间为：2020-10-07 21:44:08
     *
     * @param num 今天开始的 前num天或者后num天
     * @return String
     */
    public static String getWantDateTime(int num) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE, num);
        Date date = calendar.getTime();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(STANDARD_DATETIME_24);
        return simpleDateFormat.format(date);
    }

    /**
     * 计算当前时间是 一年中的第几天 yy-MM-dd HH:mm:ss
     *
     * @param str yy-MM-dd HH:mm:ss的时间
     * @return String
     */
    public static String getOrderInYear(String str) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(STANDARD_DATETIME_24);
        try {
            Date date = simpleDateFormat.parse(str);
            Calendar cal = Calendar.getInstance();
            cal.setTime(date);
            int days = getOrderDay(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH) + 1, cal.get(Calendar.DATE));
            return String.valueOf(days);
        } catch (ParseException e) {
            logger.error("getWhenDay() error occur :{}", e.getMessage());
            logger.error("请检查入参，样例入参为 yy-MM-dd HH:mm:ss");
            return StrUtils.EMPTY_STR;
        }
    }

    /**
     * 计算 当前参数 时间是一年中的第几天
     *
     * @param year  年
     * @param month 月
     * @param day   日
     * @return int
     */
    @SuppressWarnings("all")
    public static int getOrderDay(int year, int month, int day) {
        // 定义累加器储存天数
        int num = 0;
        // 遍历月份，求每个月份的天数和
        for (int i = 1; i < month; i++) {
            switch (i) {
                // 当月为大月时累加31
                case 1:
                case 3:
                case 5:
                case 7:
                case 8:
                case 10:
                case 12:
                    num += 31;
                    break;
                // 当月为二月时闰年累加29，平年累加28
                case 2:
                    num += (0 == year % 4 && 0 != year % 100 || 0 == year % 400) ? 29 : 28;
                    break;
                default:
                    num += 30;
                    break;
            }
        }
        // 加上日
        num += day;
        return num;
    }

    /**
     * 参数是 String 类型的时间得到 Date 类型的时间
     *
     * @param str 时间字符串
     * @return Date
     */
    public static Date getDateByStr(String str) {
        SimpleDateFormat simpleDateFormat;
        if (str.contains(":")) {
            simpleDateFormat = new SimpleDateFormat(STANDARD_DATETIME_24);
        } else {
            simpleDateFormat = new SimpleDateFormat(STANDARD_DATE);
        }
        try {
            return simpleDateFormat.parse(str);
        } catch (ParseException e) {
            logger.error(LogConst.ERROR, e.getMessage());
            return null;
        }
    }

}

